package com.movie.recomend.controller;

import com.movie.recomend.model.domain.Movie;
import com.movie.recomend.model.domain.Tag;
import com.movie.recomend.model.domain.User;
import com.movie.recomend.model.recom.Recommendation;
import com.movie.recomend.model.request.*;
import com.movie.recomend.service.*;
import com.movie.recomend.utils.Constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@CrossOrigin
@RequestMapping("/rest/movie")
@RestController
public class MovieRestApi {

    private Logger logger = LoggerFactory.getLogger(MovieRestApi.class);

//    private static Logger logger = LoggerFactory.getLogger(MovieRestApi.class.getName());

    @Autowired
    private RecommendService recommendService;

    @Autowired
    private MovieService movieService;

    @Autowired
    private UserService userService;

    @Autowired
    private RatingService ratingService;

    @Autowired
    private TagService tagService;

    /**
     * 获取推荐的电影【实时推荐6 + 内容推荐4】【bug】
     *
     * @param username
     * @param
     * @return
     */
//    @GetMapping("/guess")
//    public List getGuessMovies(@RequestParam("username") String username, @RequestParam("num") int num) {
//        User user = userService.findByUsername(username);
//        List<Recommendation> recommendations = recommendService.getHybridRecommendations(new MovieHybridRecommendationRequest(user.getUid(), num));
//        if (recommendations.size() == 0) {
//            String randomGenres = user.getPrefGenres().get(new Random().nextInt(user.getPrefGenres().size()));
//            recommendations = recommendService.getTopGenresRecommendations(new TopGenresRecommendationRequest(randomGenres.split(" ")[0], num));
//        }
//        return recommendations;
//    }

    /**
     * 根据用户特征协同过滤【测试通过】
     *
     * @param username
     * @param
     * @return
     */
    @GetMapping("/wish")
    public List getWishMovies(@RequestParam("username") String username, @RequestParam("num") int num) {
        User user = userService.findByUsername(username);
        System.out.println("controller user = " + user.getUid());
        List<Recommendation> recommendations = recommendService.getCollaborativeFilteringRecommendations(new UserRecommendationRequest(user.getUid(), num));
        if (recommendations.size() == 0) {
            String randomGenres = user.getPrefGenres().get(new Random().nextInt(user.getPrefGenres().size()));
            recommendations = recommendService.getTopGenresRecommendations(new TopGenresRecommendationRequest(randomGenres.split(" ")[0], num));
        }
        return movieService.getRecommendeMovies(recommendations);
    }

    /**
     * 获取热门推荐 【测试通过】
     *
     * @param
     * @return
     */
    @GetMapping("/hot")
    public List getHotMovies(@RequestParam("num") int num) {
        List<Recommendation> recommendations = recommendService.getHotRecommendations(new HotRecommendationRequest(num));
        List<Movie> recommendeMovies = movieService.getRecommendeMovies(recommendations);
        return recommendeMovies;
    }

    /**
     * 获取评分最多的电影 【测试通过】
     *
     * @param
     * @return
     */
    @GetMapping("/rate")
    public List getRateMoreMovies(@RequestParam("num") int num) {
        List<Recommendation> recommendations = recommendService.getRateMoreRecommendations(new RateMoreRecommendationRequest(num));
        return movieService.getRecommendeMovies(recommendations);
    }

    /**
     * 获取新添加的电影 【测试通过】
     *
     * @param
     * @return
     */
    @GetMapping("/new")
    public List getNewMovies(@RequestParam("num") int num) {
        return movieService.getNewMovies(new NewRecommendationRequest(num));
    }

    /**
     * 根据单个电影的信息 进行推荐4个电影 【测试通过】
     * 隐语义模型协同过滤
     *
     * @return
     */
    @GetMapping("/infoRec/{mid}")
    public List getSameMovie(@PathVariable("mid") int mid, @RequestParam("num") int num) {
        List<Recommendation> recommendations = recommendService.getCollaborativeFilteringRecommendations(new MovieRecommendationRequest(mid, num));
        return movieService.getRecommendeMovies(recommendations);
    }


    /**
     * 获取单个电影的信息【测试通过】
     *
     * @param mid
     * @return
     */
    @GetMapping("/info/{mid}")
    public Movie getMovieInfo(@PathVariable("mid") int mid) {
        return movieService.findByMID(mid);
    }


    /**
     * 根据单个电影的信息 进行推荐4个电影 【测试通过】
     * 内容相似性推荐
     *
     * @return
     */
    @GetMapping("/infoRecBC/{mid}")
    public List MovieInfoRecommedByContent(@PathVariable("mid") int mid, @RequestParam("num") int num) {
        MovieRecommendationRequest movieRecommendationRequest = new MovieRecommendationRequest(mid, 4);
        List<Recommendation> contentBasedMoreLikeThisRecommendations =
                recommendService.getContentBasedMoreLikeThisRecommendations(movieRecommendationRequest);
        List<Movie> recommendeMovies = movieService.getRecommendeMovies(contentBasedMoreLikeThisRecommendations);
        return recommendeMovies;
    }


    /**
     * 模糊查询电影 【测试通过】
     *
     * @param query
     * @return
     */
    @GetMapping("/search")
    public List getSearchMovies(@RequestParam("query") String query) {
        List<Recommendation> recommendations = recommendService.getContentBasedSearchRecommendations(new SearchRecommendationRequest(query, 100));
        return recommendations;
    }

    /**
     * 查询类别电影 【测试通过】
     *
     * @param category
     * @param
     * @return
     */
    @GetMapping("/genres")
    public List getGenresMovies(@RequestParam("category") String category,
                                @RequestParam("num") int num) {
        List<Recommendation> recommendations = recommendService.getContentBasedGenresRecommendations(new SearchRecommendationRequest(category, num));
        List<Movie> recommendeMovies = movieService.getRecommendeMovies(recommendations);
        return recommendeMovies;
    }

    /**
     * 获取用户评分过得电影 【测试通过】
     *
     * @param username
     * @return
     */
    @GetMapping("/myrate")
    public List<Movie> getMyRateMovies(@RequestParam("username") String username) {
        User user = userService.findByUsername(username);
        return movieService.getMyRateMovies(user.getUid());
    }


    /**
     * 评分电影埋点计算
     *
     * @param mid
     * @param score
     * @param username
     * @return
     */
    @RequestMapping(value = "/rate/{mid}", produces = "application/json", method = RequestMethod.GET)
    @ResponseBody
    public String rateToMovie(@PathVariable("mid") int mid, @RequestParam("score") Double score, @RequestParam("username") String username) {
        User user = userService.findByUsername(username);
        MovieRatingRequest request = new MovieRatingRequest(user.getUid(), mid, score);
        boolean complete = ratingService.movieRating(request);
        //埋点日志
        if (complete) {
            System.out.print("=========complete=========");
            logger.info(Constant.MOVIE_RATING_PREFIX + ":" + user.getUid() + "|" + mid + "|" + request.getScore() + "|" + System.currentTimeMillis() / 1000);
        }
        return "已完成评分";
    }


    /**
     * 获取电影的标签【测试通过】
     *
     * @param mid
     * @return
     */
    @GetMapping("/tag/{mid}")
    public List getMovieTags(@PathVariable("mid") int mid) {
        return tagService.findMovieTags(mid);
    }

    //【测试通过】
    @GetMapping("/mytag/{mid}")
    public List getMyTags(@PathVariable("mid") int mid, @RequestParam("username") String username) {
        User user = userService.findByUsername(username);
        return tagService.findMyMovieTags(user.getUid(), mid);
    }


    @RequestMapping(value = "/newtag/{mid}", produces = "application/json", method = RequestMethod.GET)
    @ResponseBody
    public Tag addMyTags(@PathVariable("mid") int mid, @RequestParam("tagname") String tagname, @RequestParam("username") String username) {
        User user = userService.findByUsername(username);
        Tag tag = new Tag(user.getUid(), mid, tagname);
        tagService.newTag(tag);
        return tag;
    }

    @GetMapping("/stat")
    public int[] getMyRatingStat(@RequestParam("username") String username) {
        User user = userService.findByUsername(username);
        return ratingService.getMyRatingStat(user);
    }


    /**
     * 获取电影的体裁列表【测试通过】
     *
     * @return
     */
    @GetMapping("/genresList")
    public List getGenresList() {
        List topGenres = recommendService.getTopGenres();
        return topGenres;
    }

}
